package ru.ifmo.network;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author avhaliullin
 */
public class UDPListener implements Runnable {
    private DatagramSocket socket;
    private final HelloMessageListener listener;
    private final Logger log = Logger.getLogger(UDPListener.class.getName());
    private final int port;

    private void initSocket() {
        try {
            log.info("Port " + port);
            this.socket = new DatagramSocket(port);
            socket.setBroadcast(true);
        } catch (SocketException e) {
            log.log(Level.SEVERE, "Can't create socket", e);
        }
    }

    public UDPListener(HelloMessageListener listener, int port) {
        this.listener = listener;
        this.port = port;
        initSocket();
    }


    public void run() {
        while (!Thread.interrupted()) {
            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            try {
                socket.receive(packet);
                log.info("Received " + packet.getLength() + " bytes");
                DataInputStream is = new DataInputStream(new BufferedInputStream(
                        new ByteArrayInputStream(buf, packet.getOffset(), packet.getLength())));
                final HelloMessage message = new HelloMessage(is.readUTF(), is.readUTF(), is.readInt());
                new Thread(new Runnable() {
                    public void run() {
                        listener.message(message);
                    }
                }).start();
            } catch (IOException e) {
                log.log(Level.WARNING, "Failed to receive datagram, try to reconnect", e);
                initSocket();
            }

        }
    }
}
